package Calculadora.Stack.StackList;
/**
 * Implementación de Stack con Listas de doble enlace
 * @param <E>  clase generica
 * @author Douglas Dávila
 * @since 12/08/2012
 * @version 1.0
 * @List
 */
public class DoublyLinkedList<E> extends AbstractList<E>{
    /**Cantidad de elementos*/
    protected int count;
    /**Referencia a la cabeza de la lista*/
    protected DoublyLinkedListElement head;
    /**Referencia a la cola de la lista */
    protected DoublyLinkedListElement tail;

    /**
     * Constructor
     * @pre N/A
     * @post Instacia una lista vacia
     * @since 12/08/2012
     */
    public DoublyLinkedList(){
        head = null;
        tail = null;
        count = 0;
    }
    
    /**
     * Agregar un valor a la cabeza de la lista
     * @param item el objeto a agregar a la lista
     * @pre N/A
     * @post El objeto es agregado al inicio de la lista
     * @since 12/08/2012
     * @see List
     */
    @Override
    public void addFirst(E item){
        head = new DoublyLinkedListElement(item, head, null);
        if (tail == null) {
            tail = head;
        }
        count++;
    }

    /**
     * Se remueve el primer objeto en la lista
     * @return El primer objeto en la lista
     * @pre que la lista no este vacia
     * @post se remueve el primer objeto en la lista
     * @since 12/08/2012
     * @see List
     */
    @Override
    public E removeFirst(){
        DoublyLinkedListElement temp = head;
        head = head.next();
        if (head != null) {
            head.setPreviousData(null);
        } else {
            tail = null; 
        }
        temp.setNextData(null);
        count--;
        return (E) temp.value();
    }

    /**
     * Se obtiene la referencia del primer objeto en la lista
     * @return la referencia del primer objeto en la lista
     * @pre que la lista no este vacia
     * @post retorna la referencia del primero objeto en la lista
     * @since 12/08/2012
     * @see List
     */
    @Override
    public E getFirst(){
        return (E) head.value();
    }

    /**
    * Determina la cantidad de objetos de la lista
    * @return cantidad de objetos de la lista
    * @pre N/A
    * @post retorna la cantidad de objetos de la lista
    * @since 12/08/2012
    * @see List
    */
    @Override
    public int size(){
        return count;
    }
}
